package threadPoolDemo;

import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author Ajie
 * @date 2019-09-06
 * @function
 *
 * 控制  BlockingQueue<Runnable> size
 * 结论：
 * newFixedThreadPool 固定线程池，调用 {@link ThreadPoolExecutor#getQueue()}拿到runnbale数量来控制，队列长度。
 *
 * newSingleThreadExecutor，无法调用到{@link Executors.FinalizableDelegatedExecutorService} 无法获得队列长度。
 *
 * newCachedThreadPool ，没有设置 coreThread num ,迅速来到oom
 */
public class SingleThreadPool {
    public static void main(String[] args) {
        chotrolQueueNum();

        System.out.println("over ----------");

    }

    private static void chotrolQueueNum() {
        //        ExecutorService threadPoolDemo = Executors.newSingleThreadExecutor();
//        ExecutorService threadPoolDemo = Executors.newFixedThreadPool(1);
        ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(1);
//        ExecutorService threadPoolDemo = Executors.newCachedThreadPool();// todo 最快来到oom ,java.lang.OutOfMemoryError: unable to create new native thread


        //结果，for瞬间来到千万级别， 循环很久很久没有执行完成。猜测原因，进程创建 runnable 耗时 。
        // TODO exception
        //--------out41784124
        //50004  num
        //Exception in thread "main" 50005  num
        //50006  num
        //java.lang.OutOfMemoryError: GC overhead limit exceeded
        //50007  num
        //	at java.nio.CharBuffer.wrap(CharBuffer.java:373)
        //	at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:265)
        //	at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
        //	at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)
        //	at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)
        //	at java.io.PrintStream.newLine(PrintStream.java:545)
        //	at java.io.PrintStream.println(PrintStream.java:807)
        //	at threadPoolDemo.SingleThreadPool.main(SingleThreadPool.java:30)
        //Exception in thread "pool-1-thread-1" java.lang.OutOfMemoryError: GC overhead limit exceeded
        //	at threadPoolDemo.SingleThreadPool$1.run(SingleThreadPool.java:21)
        //	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        //	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        //	at java.lang.Thread.run(Thread.java:748)

//        for (int i = 0; i < Integer.MAX_VALUE; i++) {
        for (int i = 0; i < 10; i++) {
            int finalI = i;
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    ThreadPoolExecutor executor = (ThreadPoolExecutor) threadPool;
//                    ThreadPoolExecutor executor = threadPoolDemo;
                    System.out.println(finalI +"  num  activeCount " + executor.getActiveCount()+"  taskCount"+executor.getTaskCount() + " BlockingQueue<Runnable> size :"+executor.getQueue().size());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });

//            System.out.println("--------out"+finalI);
        }
    }
}
